#include "GlCamera.h"

#include "GlMatrix4x4.h"
#include "GlCommon.h"
#include "GlVector4.h"
#include "GlWindow.h"
#include "Utility.h"

namespace GraphicLibrary
{
	Camera *Camera::msSingleton(0);
	//---------------------------------------------------
	void Camera::lookAt(const Position &target)
	{
		mDirection = getAngleTo(mPosition, target) - Utility::Pi * 0.5f;
	}

	//---------------------------------------------------
	Matrix4x4 Camera::getTransformationMatrix() const
	{
		Matrix4x4 mat;
		mat.setTranslocation(-mPosition.mX, -mPosition.mY, 0.0f);
		Matrix4x4 tmp;
		tmp.setScale(mPixelMultiplier * 2.0f, mPixelMultiplier * 2.0f, 1.0f);
		mat *= tmp;
		tmp.setRotationZ(-mDirection);
		mat *= tmp;
		return mat;
	}

	//---------------------------------------------------
	Position Camera::projectScreenSpaceToGameSpace(const float x, const float y) const
	{
		Matrix4x4 invTrans = getInvTransformationMatrix();
		Vector4 vec;
		vec(0) = mWindow->getClientAreaWidth() * 0.5f * x + mWindow->getClientAreaWidth() * -0.5f * (1.0f - x);
		vec(1) = mWindow->getClientAreaHeight() * -0.5f * y + mWindow->getClientAreaHeight() * 0.5f * (1.0f - y);
		vec(2) = 0.0f;
		vec(3) = 1.0f;
		vec = vec * invTrans;
		return Position(vec(0), vec(1));
	}

	//---------------------------------------------------
	Matrix4x4 Camera::getInvTransformationMatrix() const
	{
		Matrix4x4 mat;
		mat.setRotationZ(mDirection);
		Matrix4x4 tmp;
		tmp.setScale(1.0f / mPixelMultiplier, 1.0f / mPixelMultiplier, 1.0f);
		mat *= tmp;
		tmp.setTranslocation(mPosition.mX, mPosition.mY, 0.0f);
		mat *= tmp;
		return mat;
	}
}
